package com.phaeton.beemeup;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.andengine.engine.camera.ZoomCamera;
import org.andengine.engine.camera.hud.HUD;
import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.entity.IEntity;
import org.andengine.entity.shape.IAreaShape;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.text.Text;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.util.SAXUtils;
import org.andengine.util.color.Color;
import org.andengine.util.debug.Debug;
import org.andengine.util.level.IEntityLoader;
import org.andengine.util.level.LevelLoader;
import org.xml.sax.Attributes;

import android.util.Log;

import com.phaeton.beemeup.constants.LevelConstants;
import com.phaeton.beemeup.constants.SceneConstants;
import com.phaeton.beemeup.entity.Bee;
import com.phaeton.beemeup.entity.BeeComb;
import com.phaeton.beemeup.entity.Cell;
import com.phaeton.beemeup.entity.Comb;
import com.phaeton.beemeup.entity.Fight;
import com.phaeton.beemeup.entity.Flower;
import com.phaeton.beemeup.entity.HomeComb;
import com.phaeton.beemeup.entity.IComb;
import com.phaeton.beemeup.entity.Insect;
import com.phaeton.beemeup.entity.NewComb;
import com.phaeton.beemeup.entity.Wasp;
import com.phaeton.beemeup.entity.WaspComb;
import com.phaeton.beemeup.gui.IngameMenu;
import com.phaeton.beemeup.gui.ItemBar;
import com.phaeton.beemeup.updatehandlers.BeeHandler;
import com.phaeton.beemeup.updatehandlers.WaspHandler;
import com.phaeton.beemeup.util.Coordinate;
import com.phaeton.beemeup.util.TouchDetector;

public class GameManager {
	private BeeMeUpActivity mActivity;

	private AnimatedSprite selectedSprite;	

	public UUID selectedBee;	
	public Map<UUID, Bee> mBees;
	public Map<UUID, Wasp> mWasps;
	public Map<UUID, Flower> mFlowers;
	public Map<UUID, BeeComb> mBeeCombs;
	public Map<UUID, WaspComb> mWaspCombs;

	private Level mLevel;
	private LevelLoader mLevelLoader;
//	private ArrayList<UUID> gatheringBees;
//	private ArrayList<UUID> dumpingBees;
	private ArrayList<IAreaShape> newCombs;
//	private ArrayList<UUID> gatheringWasps;
//	private ArrayList<UUID> dumpingWasps;
	private ArrayList<Fight> fights;
	private int maxBees;
	private int maxWasps;
	private Coordinate waspHome;
	private HomeComb mHomeComb;

	private HUD mHUD;
	private ItemBar mItemBar;
	private IngameMenu mMenu;
	
	private ZoomCamera mCamera;
	
	public GameManager(BeeMeUpActivity pActivity, ZoomCamera pCamera){
		mActivity = pActivity;
		mCamera = pCamera;
	}
	
	public void init(){
		mBees = new ConcurrentHashMap<UUID, Bee>();
		mWasps = new ConcurrentHashMap<UUID, Wasp>();
		mFlowers = new ConcurrentHashMap<UUID, Flower>();	
		mBeeCombs = new ConcurrentHashMap<UUID, BeeComb>();	
		mWaspCombs = new ConcurrentHashMap<UUID, WaspComb>();	
//		gatheringBees = new ArrayList<UUID>();
//		dumpingBees = new ArrayList<UUID>();
		newCombs = new ArrayList<IAreaShape>();
//		gatheringWasps = new ArrayList<UUID>();
//		dumpingWasps = new ArrayList<UUID>();
		fights = new ArrayList<Fight>();
		
		setSelectedSprite(mActivity.getSceneManager().getTiledTexture("Select"));
		
		mLevel = new Level(mActivity.getSceneManager().getTexture("NewComb"), mActivity.getVertexBufferObjectManager());				
        mLevel.setOnSceneTouchListener(new TouchDetector(this));
        
        this.mLevelLoader = new LevelLoader();
        mLevelLoader.setAssetBasePath("lvl/");
        this.registerLevelLoaders();
	}
	
	public void setSelectedSprite(ITiledTextureRegion iTiledTextureRegion){
		selectedSprite = new AnimatedSprite(0, 0, iTiledTextureRegion, mActivity.getVertexBufferObjectManager());
		selectedSprite.setScaleCenter(0, 0);
		selectedSprite.setScale(4);
	}
	
	public AnimatedSprite getSelectedSprite(){
		return selectedSprite;
	}

	public void registerUpdateHandler(IUpdateHandler iUpdateHandler) {
		mLevel.registerUpdateHandler(iUpdateHandler);
	}

	public void addFight(final Fight fight){
		fights.add(fight);
		
		mLevel.getChildByIndex(SceneConstants.LAYER_BEES).attachChild(fight);
		mLevel.registerTouchArea(fight);
	}
	
	public void removeFight(final Fight fight){
		//Log.e("Fight", "remove fight");
		
		fights.remove(fight);
				
		mActivity.runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
			/* Now it is save to remove the entity! */
				mLevel.getChildByIndex(SceneConstants.LAYER_BEES).detachChild(fight);
			}
		});
		mLevel.unregisterTouchArea(fight);
	}
	
	public ArrayList<Fight> getFights(){
		return fights;
	}
	
	public void destroyBeeComb(final UUID comb) {
		Log.e("GM", "Start");
		Log.e("GM", "if mBeeCombs.contains..."+mBeeCombs.containsKey(comb));
		mActivity.runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
				Log.e("GM", "Run gestartet");
				/* Now it is save to remove the entity! */
//				mLevel.getChildByIndex(SceneConstants.LAYER_COMBS).detachChild(mBeeCombs.get(comb));
				if(mBeeCombs.get(comb).hasParent()) mBeeCombs.get(comb).detachSelf();
        mLevel.getCell(mBeeCombs.get(comb).getCol(), mBeeCombs.get(comb).getRow()).removeState(Cell.IS_BEECOMB);
        mLevel.unregisterTouchArea(mBeeCombs.get(comb));
				mBeeCombs.remove(comb);
				Log.e("GM", "detach");
			}
		});
	}
	
	public void destroyWaspComb(final UUID comb) {
		Log.e("GM", "Start");
		Log.e("GM", "if mWaspCombs.contains..."+mWaspCombs.containsKey(comb));
		mActivity.runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
				Log.e("GM", "Run gestartet");
				/* Now it is save to remove the entity! */
//				mLevel.getChildByIndex(SceneConstants.LAYER_COMBS).detachChild(mBeeCombs.get(comb));
				if(mWaspCombs.get(comb).hasParent()) mWaspCombs.get(comb).detachSelf();
        mLevel.unregisterTouchArea(mWaspCombs.get(comb));
        mLevel.getCell(mWaspCombs.get(comb).getCol(), mWaspCombs.get(comb).getRow()).removeState(Cell.IS_WASPCOMB);
        
        for(Wasp wasp: mWasps.values()){				
           if(mBeeCombs.get(comb).getOccupant() != null && mBeeCombs.get(comb).getOccupant().equals(wasp)){
              wasp.removeState(Insect.COLLECTING);
              wasp.removeState(Insect.DUMPING);
              wasp.removeState(Insect.REGENERATION);
              wasp.removeState(Insect.ARRIVING);
           }
        }
        for(Bee bee: mBees.values()){				
           if(mBeeCombs.get(comb).getOccupant() != null && mBeeCombs.get(comb).getOccupant().equals(bee)){
              bee.removeState(Insect.COLLECTING);
              bee.removeState(Insect.DUMPING);
              bee.removeState(Insect.REGENERATION);
              bee.removeState(Insect.ARRIVING);
           }
        }
        
				mWaspCombs.remove(comb);
				Log.e("GM", "detach");
			}
		});
		
		for(Bee bee: mBees.values()){				
			if(mWaspCombs.get(comb).getOccupant() != null && mWaspCombs.get(comb).getOccupant().equals(bee)){
				bee.removeState(Insect.COLLECTING);
				bee.removeState(Insect.DUMPING);
				bee.removeState(Insect.REGENERATION);
				bee.removeState(Insect.ARRIVING);
			}
		}
		for(Wasp wasp: mWasps.values()){				
			if(mWaspCombs.get(comb).getOccupant() != null && mWaspCombs.get(comb).getOccupant().equals(wasp)){
				wasp.removeState(Insect.COLLECTING);
				wasp.removeState(Insect.DUMPING);
				wasp.removeState(Insect.REGENERATION);
				wasp.removeState(Insect.ARRIVING);
			}
		}
	}
	
	public void destroyWasp(final UUID wasp) {
		//wasp.detachSelf();
		mActivity.runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
			/* Now it is save to remove the entity! */
				mLevel.getChildByIndex(SceneConstants.LAYER_BEES).detachChild(mWasps.get(wasp));
        mLevel.unregisterTouchArea(mWasps.get(wasp));
		
        for(WaspComb comb: mWaspCombs.values()){				
           if(comb.getOccupant() != null && comb.getOccupant().equals(mWasps.get(wasp))){
              comb.deOccupy();
           }
        }
        for(Flower flower: mFlowers.values()){				
           if(flower.getOccupant() != null && flower.getOccupant().equals(mWasps.get(wasp))){
              flower.deOccupy();
           }
        }
        mLevel.unregisterTouchArea(mWasps.get(wasp));
        mWasps.remove(wasp);
           }
        });
	}
	
	public void destroyBee(final UUID bee) {
		//Log.e("DestroyBee", "destroy bee "+bee);
		
		mActivity.runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
			/* Now it is save to remove the entity! */
				if(mBees.containsKey(bee)) mLevel.getChildByIndex(SceneConstants.LAYER_BEES).detachChild(mBees.get(bee));
		
        for(BeeComb comb: mBeeCombs.values()){				
           if(comb.getOccupant() != null && comb.getOccupant().equals(mBees.get(bee))){
              comb.deOccupy();
           }
        }
        for(Flower flower: mFlowers.values()){				
           if(flower.getOccupant() != null && flower.getOccupant().equals(mBees.get(bee))){
              flower.deOccupy();
           }
        }
		
        mLevel.unregisterTouchArea(mBees.get(bee));
        mBees.remove(bee);
           }
        });
	}
   
   private void spawnBee(int col, int row){
		Bee bee = new Bee(mLevel.getCell(col, row).getX(), mLevel.getCell(col, row).getY(), GameManager.this);
		bee.setAnimData(0, 1, 0, 1, 2, 3);
//		bee.setTarget(mHomeComb);
//		bee.fly();
		mLevel.registerTouchArea(bee);
		mBees.put(UUID.randomUUID(), bee);
		mLevel.getChildByIndex(SceneConstants.LAYER_BEES).attachChild(bee);		
	}
   
   public void spawnWasp(int col, int row){
	    Wasp wasp = new Wasp(mLevel.getCell(col, row).getX(), mLevel.getCell(col, row).getY(), GameManager.this);
		wasp.setAnimData(0, 1, 0, 1, 2, 3);
		mLevel.registerTouchArea(wasp);
		mWasps.put(UUID.randomUUID(), wasp);
		mLevel.getChildByIndex(SceneConstants.LAYER_BEES).attachChild(wasp);
	}
   
   //build new wasp comb (KI)
   public void spawnWaspComb(WaspComb oldComb) {
	   int[][] surroundingCombs = new int[6][2];
	   int[] weights = new int[6];
	   int col = oldComb.getCol(); 
	   int row = oldComb.getRow();
	   
	   for(int i = 0; i < surroundingCombs.length; i++ ) {
		   surroundingCombs[i][0] = - 1;
		   surroundingCombs[i][1] = - 1;
	   }
	   //fill surroundingCombs
	   //0
	   if(row > 0) {
		   surroundingCombs[0][0] = col;
		   surroundingCombs[0][1] = row - 1;
	   }
	   //3
	   if(row < mLevel.getDimension().getRow() - 1) {
		   surroundingCombs[3][0] = col;
		   surroundingCombs[3][1] = row + 1;
	   }
	   //even column
	   if(col % 2 == 0){
		   //5
		   if(col > 0) {
			   surroundingCombs[5][0] = col - 1;
			   surroundingCombs[5][1] = row - 1;
		   }
		   //1
		   if(col < mLevel.getDimension().getColumn() - 1) {
			   surroundingCombs[1][0] = col+1;
			   surroundingCombs[1][1] = row - 1;
		   }
		   //2
		   if(col < mLevel.getDimension().getColumn() - 1 && row < mLevel.getDimension().getRow() - 1) {
			   surroundingCombs[2][0] = col + 1;
			   surroundingCombs[2][1] = row;
		   }
		   //4
		   if(col < mLevel.getDimension().getColumn() - 1 && row < mLevel.getDimension().getRow() - 1) {
			   surroundingCombs[4][0] = col - 1;
			   surroundingCombs[4][1] = row;
		   }
	   }
	   //odd column
	   else{
			//5
		   if(col > 0 && row > 0) {
			   surroundingCombs[5][0] = col - 1;
			   surroundingCombs[5][1] = row;
		   }
		   //1
		   if(row > 0 && col < mLevel.getDimension().getColumn() - 1) {
			   surroundingCombs[1][0] = col + 1;
			   surroundingCombs[1][1] = row;
		   }
		   //2
		   if(col < mLevel.getDimension().getColumn() - 1) {
			   surroundingCombs[2][0] = col + 1;
			   surroundingCombs[2][1] = row + 1;
		   }
		   //4
		   if(col < mLevel.getDimension().getColumn() - 1) {
			   surroundingCombs[4][0] = col - 1;
			   surroundingCombs[4][1] = row + 1;
		   }
		}

	   //Checking and weighting of neighborhood
	   for(int i = 0; i < surroundingCombs.length; i++) {
		   if(surroundingCombs[i][0] < 0 || surroundingCombs[i][0] >= mLevel.getDimension().getColumn() || 
				   surroundingCombs[i][1] < 0 || surroundingCombs[i][1] >= mLevel.getDimension().getRow() || 
				   mLevel.getCell(surroundingCombs[i][0], surroundingCombs[i][1]).getState() != Cell.FREE) {
			   weights[i] = - 1;
		   } 
		   else if(mLevel.getCell(surroundingCombs[i][0], surroundingCombs[i][1]).getState() == Cell.IS_WASPCOMB) {
			   if(i == surroundingCombs.length - 1) {
				   weights[i-1] += 10;
				   weights[0] += 10; 
			   }
			   else if(i == 0) {
				   weights[surroundingCombs.length - 1] += 10;
				   weights[1] += 10;
			   }
			   else if(i < surroundingCombs.length) {
				   weights[i-1] += 10;
				   weights[i+1] += 10;
			   }
		   }
	   }

	   Random random = new Random();
       for(int i = 0; i< 100;i++){
           for(int j = 0; j < surroundingCombs.length; j++){
        	   if(weights[j] >= 0) weights[j] += random.nextInt(15);
           }
       }
       
	   int counter = -1;
	   int highestWeight = weights[0];
	   
	   for(int i = 0; i < surroundingCombs.length; i++) {
		   if((highestWeight < weights[i]) && (weights[i] > -1)) {
			   counter = i;
			   highestWeight = weights[i];
		   }
	   }
	   
	   if(counter > -1 && weights[counter] > -1) {
		   col = surroundingCombs[counter][0];
		   row = surroundingCombs[counter][1];
		   
		   WaspComb newComb = new WaspComb(col, row,
				   mActivity.getSceneManager().getTiledTexture("WaspComb"), 
				   mActivity.getVertexBufferObjectManager(),
				   GameManager.this);
		   mLevel.getCell(col, row).addState(Cell.IS_WASPCOMB);
		   mWaspCombs.put(UUID.randomUUID(), newComb);
	
		   oldComb.addMaterial(-5);
		   mLevel.getChildByIndex(SceneConstants.LAYER_COMBS).attachChild(newComb);
		   mLevel.registerTouchArea(newComb);
	   }else{
		   oldComb.addState(Comb.SURROUNDED);
	   }
   }
	
	//build new bee comb (by user)
	public void spawnBeeComb(final int col, final int row, int honey) {
		BeeComb comb = new BeeComb(
				col,
				row,
				mActivity.getSceneManager().getTiledTexture("BeeComb"),
				GameManager.this);
		mLevel.getCell(col, row).addState(Cell.IS_BEECOMB);
		mBeeCombs.put(UUID.randomUUID(), comb);
				
		mLevel.registerTouchArea(comb);
		comb.setHoney(honey);
		mLevel.getChildByIndex(SceneConstants.LAYER_COMBS).attachChild(comb);
	}
	
	//activate new comb
	public void showNewComb(final BeeComb comb, final int col, final int row){
		NewComb newComb = new NewComb(comb, col, row, mActivity.getSceneManager().getTexture("NewComb"), this);
		newCombs.add(newComb);
		mLevel.getChildByIndex(SceneConstants.LAYER_GUI).attachChild(newComb);
		mLevel.registerTouchArea(newComb);
	}
	
	//deactivate new comb
	public void hideNewCombs(){
		for(IAreaShape shape: newCombs){
			shape.detachSelf();
			mLevel.unregisterTouchArea(shape);
		}
	}
	
   public BeeMeUpActivity getActivity(){
		return mActivity;
	}

	public Level getLevel() {
		return mLevel;
	}

	public UUID getSelectedBee() {
		return selectedBee;
	}

	public Map<UUID, Bee> getBees() {
		return mBees;
	}

	public Map<UUID, Wasp> getWasps() {
		return mWasps;
	}

	public Map<UUID, Flower> getFlowers() {
		return mFlowers;
	}

	public Map<UUID, BeeComb> getBeeCombs() {
		return mBeeCombs;
	}

	public Map<UUID, WaspComb> getWaspCombs() {
		return mWaspCombs;
	}
	
	public ArrayList<IAreaShape> getNewCombs() {
		return newCombs;
	}

	public int getMaxBees() {
		return maxBees;
	}

	public int getMaxWasps() {
		return maxWasps;
	}

	public Coordinate getWaspHome(){
		return waspHome;
	}

	public HomeComb getHomeComb() {
		return mHomeComb;
	}

	public ItemBar getItemBar() {
		return mItemBar;
	}

	public ZoomCamera getCamera(){
		return mCamera;
	}

	public void setSelectedSprite(AnimatedSprite selectedSprite) {
		this.selectedSprite = selectedSprite;
	}

	public void setSelectedBee(UUID selectedBee) {
		this.selectedBee = selectedBee;
	}

	public void setBees(Map<UUID, Bee> mBees) {
		this.mBees = mBees;
	}

	public void setWasps(Map<UUID, Wasp> mWasps) {
		this.mWasps = mWasps;
	}

	public void setFlowers(Map<UUID, Flower> mFlowers) {
		this.mFlowers = mFlowers;
	}

	public void setBeeCombs(Map<UUID, BeeComb> mBeeCombs) {
		this.mBeeCombs = mBeeCombs;
	}

	public void setWaspCombs(Map<UUID, WaspComb> mWaspCombs) {
		this.mWaspCombs = mWaspCombs;
	}
	
	public void setNewCombs(ArrayList<IAreaShape> newCombs) {
		this.newCombs = newCombs;
	}

	public void setMaxBees(int maxBees) {
		this.maxBees = maxBees;
	}

	public void setMaxWasps(int maxWasps) {
		this.maxWasps = maxWasps;
	}

	public void setHomeComb(HomeComb mHomeComb) {
		this.mHomeComb = mHomeComb;
	}

	public void setItemBar(ItemBar mItemBar) {
		this.mItemBar = mItemBar;
	}

	public void registerLevelLoaders(){
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_LEVEL, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				final int columns = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_COLUMNS);
				final int rows = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_ROWS);
				final int levelID = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_UID);
				
				mLevel.setDimension(columns, rows);
				mLevel.buildLevel();

				float width = (columns+1)*(mActivity.getSceneManager().getTexture("NewComb").getWidth()+(float)Math.sin(Math.PI/6)*mActivity.getSceneManager().getTexture("NewComb").getHeight())/2;
				float height = (rows+1.5f)*mActivity.getSceneManager().getTexture("NewComb").getHeight();
				
				//Log.e("BeeLevel", columns +","+rows + " : " + mActivity.getSceneManager().getTexture("NewComb").getWidth() + ", " + width);
				
				mCamera.setBounds(0, 0, width, height);
								
				mActivity.getSceneManager().getTexture("Background").setTextureWidth(width);
				mActivity.getSceneManager().getTexture("Background").setTextureHeight(height);
				
				mLevel.setBackgroundEnabled(false);
				mLevel.getChildByIndex(SceneConstants.LAYER_BACKGROUND).attachChild(new Sprite(0, 0, mActivity.getSceneManager().getTexture("Background"), mActivity.getVertexBufferObjectManager()));
				
				//GUI
				mHUD = new HUD();
				mCamera.setHUD(mHUD);
				mHUD.setTouchAreaBindingOnActionDownEnabled(true);
				
				mHUD.attachChild(new Sprite(mCamera.getWidth() - 180, 10, mActivity.getSceneManager().getTexture("CombHUD"), mActivity.getVertexBufferObjectManager()));
				final Text tCombCount = new Text(mCamera.getWidth() - 140, 10, mActivity.getSceneManager().getFont(), mBeeCombs.size()+"", 3, mActivity.getVertexBufferObjectManager());
				tCombCount.setColor(Color.YELLOW);
				mHUD.attachChild(tCombCount);
				
				mHUD.attachChild(new Sprite(mCamera.getWidth() - 110, 10, mActivity.getSceneManager().getTexture("BeeHUD"), mActivity.getVertexBufferObjectManager()));
				final Text tBeeCount = new Text(mCamera.getWidth() - 70, 10, mActivity.getSceneManager().getFont(), mBees.size() + "/" + maxBees, 5, mActivity.getVertexBufferObjectManager());
				tBeeCount.setColor(Color.YELLOW);
				mHUD.attachChild(tBeeCount);								

				mHUD.registerUpdateHandler(new IUpdateHandler() {
					public void onUpdate(float pSecondsElapsed) {
						tCombCount.setText(mBeeCombs.size()+"");
						tBeeCount.setText(mBees.size() + "/" + maxBees);
					}

					public void reset() {
					}
		          });
				
				mItemBar = new ItemBar(
						new Sprite(0,0,mActivity.getSceneManager().getTexture("ItemBar"), mActivity.getVertexBufferObjectManager()),
						new Sprite(0,0,mActivity.getSceneManager().getTexture("Menu"), mActivity.getVertexBufferObjectManager()){
							@Override
							public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
								
								
								return false;							
							}
						},
						new Sprite(0,0,mActivity.getSceneManager().getTexture("EmptySlot"), mActivity.getVertexBufferObjectManager()),
						new Sprite(0,0,mActivity.getSceneManager().getTexture("EmptySlot"), mActivity.getVertexBufferObjectManager()),
						new Sprite(0,0,mActivity.getSceneManager().getTexture("EmptySlot"), mActivity.getVertexBufferObjectManager()),
						new Sprite(0,0,mActivity.getSceneManager().getTexture("EmptySlot"), mActivity.getVertexBufferObjectManager()),
						new Sprite(0,0,mActivity.getSceneManager().getTexture("EmptySlot"), mActivity.getVertexBufferObjectManager()),
						new Sprite(0,0,mActivity.getSceneManager().getTexture("SpawnBeeDeactivated"), mActivity.getVertexBufferObjectManager()){
							@Override
							public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
								if(pSceneTouchEvent.isActionDown() && mBees.size() < maxBees && (mHomeComb.getState() & (IComb.OCCUPIED | IComb.RESERVED)) == 0){
									spawnBee(mHomeComb.getCol(), mHomeComb.getRow());
									//Log.e("BeeSpawn", "spawn new Bee");
									return true;
								}
								
								return false;							
							}
						}
				);
				mItemBar.setPosition(0, mCamera.getHeight() - 120);
				mItemBar.setCamera(mCamera);
				
				mHUD.setChildScene(mItemBar);
				
				//Menu
				mMenu = new IngameMenu(mCamera);
				return null;
			}			
		});
		
		//build bee
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_BEE, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				final int col = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_COLUMN);
				final int row = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_ROW);
				
				spawnBee(col, row);
				
				return null;
			}			
		});

		//build wasp
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_WASP, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				final int col = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_COLUMN);
				final int row = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_ROW);
				
				Wasp wasp = new Wasp(mLevel.getCell(col, row).getX(), mLevel.getCell(col, row).getY(), GameManager.this);
				wasp.setAnimData(0, 1, 0, 1, 2, 3);
				wasp.stop();
				mWasps.put(UUID.randomUUID(), wasp);
				mLevel.getChildByIndex(SceneConstants.LAYER_BEES).attachChild(wasp);
				
				return null;
			}			
		});
				
		//build home comb
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_HOMECOMB, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				final int col = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_COLUMN);
				final int row = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_ROW);
				final int honey = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_HONEY);
																
				mHomeComb = new HomeComb(
						col,
						row,
						mActivity.getSceneManager().getTiledTexture("HomeComb"),
						GameManager.this);
				mLevel.getCell(col, row).addState(Cell.IS_BEECOMB);
				mBeeCombs.put(UUID.randomUUID(), mHomeComb);
				mLevel.registerTouchArea(mHomeComb);
				mHomeComb.setHoney(honey);
				mLevel.getChildByIndex(SceneConstants.LAYER_COMBS).attachChild(mHomeComb);
				mCamera.setCenter(mHomeComb.getX(), mHomeComb.getY());
				
				return null;
			}			
		});
		
		//build bee comb
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_BEECOMB, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				final int col = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_COLUMN);
				final int row = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_ROW);
				final int honey = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_HONEY);
//						
//						for(int i = 0; i < mLevel.getDimension().getColumn(); i++){
//							for(int j = 0; j < mLevel.getDimension().getRow(); j++){
//								Log.e("Bee", mLevel.getCell(i,j)+" "+i+":"+j);
//							}
//						}
										
				spawnBeeComb(col, row, honey);
				
				return null;
			}			
		});

		//build wasp comb
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_WASPCOMB, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				final int col = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_COLUMN);
				final int row = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_ROW);
				final int mat = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_MATERIAL);

				WaspComb comb = new WaspComb(col, row, 
						mActivity.getSceneManager().getTiledTexture("WaspComb"), mActivity.getVertexBufferObjectManager(), GameManager.this);
				mLevel.getCell(col, row).addState(Cell.IS_WASPCOMB);
				mWaspCombs.put(UUID.randomUUID(), comb);
				comb.setMaterial(mat);
				mLevel.getChildByIndex(SceneConstants.LAYER_COMBS).attachChild(comb);
				waspHome = new Coordinate(col, row);
				return null;
			}			
		});

		//build flower
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_FLOWER, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				final int col = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_COLUMN);
				final int row = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_ROW);
				final int honey = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_HONEY);
				final int material = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_MATERIAL);

				Flower flower = new Flower(mLevel.getCell(col, row).getX(), mLevel.getCell(col, row).getY(), mActivity.getSceneManager().getTiledTexture("Flower"), GameManager.this);
				flower.setMaterial(material);
				flower.setHoney(honey);
				mLevel.getCell(col, row).addState(Cell.IS_FLOWER);
				mLevel.registerTouchArea(flower);
				mLevel.getChildByIndex(SceneConstants.LAYER_COMBS).attachChild(flower);
				mFlowers.put(UUID.randomUUID(), flower);
				
				return null;
			}			
		});
		
		//build background
	   mLevelLoader.registerEntityLoader(LevelConstants.TAG_BACKGROUND, new IEntityLoader() {
			public IEntity onLoadEntity(String pEntityName,
					Attributes pAttributes) {
				return null;
			}			
		});
	   
	   maxBees = mBees.size();
		
	   maxWasps = mWasps.size();
	}

   public Level loadLevel(String level){
		try {
			mLevelLoader.loadLevelFromAsset(mActivity.getAssets(), level);
		} catch (final IOException e) {
			Debug.e(e);
		}
		
	   mLevel.registerUpdateHandler(new IUpdateHandler() {
			public void onUpdate(float pSecondsElapsed) {
				if(selectedBee != null && mBees.get(selectedBee) != null) selectedSprite.setPosition(mBees.get(selectedBee));
				else{
					selectedSprite.stopAnimation();
					getLevel().getChildByIndex(SceneConstants.LAYER_COMBS).detachChild(selectedSprite);
				}
			}

			public void reset() {
			}
         });
       
//       new FlowerHandler(this).init();
//       new InsectHandler(this).init();
       new BeeHandler(this).init();
       new WaspHandler(this).init();
//       new CombHandler(this).init();
		
		return mLevel;
   }
   
   public void unloadLevel(){
	    mLevel.clearChildScene();
	    mLevel.clearEntityModifiers();
	    mLevel.clearTouchAreas();
	    mLevel.clearUpdateHandlers();
	    mLevel.reset();
	    mLevel.setOnSceneTouchListener(null);
	    mLevel.dispose();
	   
	    mBees.clear();
		mWasps.clear();
		mFlowers.clear();	
		mBeeCombs.clear();	
		mWaspCombs.clear();	
//		gatheringBees.clear();
//		dumpingBees.clear();
		newCombs.clear();
//		gatheringWasps.clear();
//		dumpingWasps.clear();
		
		mCamera.setBounds(0, 0, 800, 480);
		maxBees = 1;
		mCamera.setHUD(null);
   }

}
